{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## task3 数据结构\n",
    "之前我们学习python的基础，比如变量，数据类型，简单的列表，条件和循环语句，基本面向对象还有文件I/O。\n",
    "有了上面的基础，我可以更好的学习Python中各种常用数据结构的用法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 列表\n",
    "首先我们重新创建列表，然后学习一些列表的方法，最后完成一些小任务。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 创建列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#创建列表\n",
    "empty = [] #可以初始化为空列表   \n",
    "student = ['haha','hehe','heihei'] #字符串列表\n",
    "score = [100,36,90,45,77,25,95]  #数值列表\n",
    "age = [18,'弱冠','而立'] #多种类型也可以"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n",
      "36\n",
      "95\n",
      "95\n"
     ]
    },
    {
     "ename": "IndexError",
     "evalue": "list index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-3-28f6c134b6b5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscore\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[1;31m#超出范围呢?\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscore\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m7\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m: list index out of range"
     ]
    }
   ],
   "source": [
    "#索引\n",
    "#获取第一个数据\n",
    "print(score[0])\n",
    "#获取第二个数据\n",
    "print(score[1])\n",
    "#获取最后一个数据\n",
    "print(score[6])\n",
    "print(score[-1])\n",
    "#超出范围呢?\n",
    "print(score[7])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 36, 90, 45, 77]\n",
      "[100, 36, 90, 45, 77]\n",
      "[36, 90, 45]\n",
      "[]\n",
      "[]\n",
      "[77, 25]\n",
      "[77, 25, 95]\n",
      "[77, 25, 95]\n"
     ]
    }
   ],
   "source": [
    "#切片：通过索引选择列表中部分值\n",
    "#选取score中前第5的数据\n",
    "print(score[0:5])\n",
    "print(score[:5])\n",
    "#选取score第2-4个元素\n",
    "print(score[1:4])\n",
    "#选取第4-2个元素?\n",
    "print(score[4:1])\n",
    "#选取倒数第一，到倒数第3?\n",
    "print(score[-1:-3])\n",
    "print(score[-3:-1])\n",
    "print(score[-3:])\n",
    "print(score[-3:7])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 36, 90, 45, 77, 25, 95] [100, 90, 77, 95]\n",
      "[100, 90, 77, 95]\n",
      "[100]\n",
      "[95, 77, 90, 100]\n"
     ]
    }
   ],
   "source": [
    "#带步长的切片 list[start:end:step]\n",
    "#选取第1，3，5，7个数字\n",
    "print(score,score[0:7:2])\n",
    "print(score[0::2])\n",
    "#步长为-2呢？\n",
    "print(score[0::-2])\n",
    "print(score[6::-2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[95, 25, 77, 45, 90, 36, 100]\n"
     ]
    }
   ],
   "source": [
    "#任务，根据以上所学，得到score中数据反过来的列表\n",
    "fan = score[::-1]\n",
    "print(fan)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]\n",
      "[95, 25, 77, 88, 88, 45, 90, 36, 100]\n"
     ]
    }
   ],
   "source": [
    "#可以通过切片方式替换或者插入数据\n",
    "fan = [95, 25, 77, 45, 90, 36, 100]\n",
    "print(fan[3:3]) #3:3不会选中任何元素，但我可以在这个位置前插入数据\n",
    "fan[3:3] = [88,88] #3:3是没有东西的，赋值[88,88],其实是在这个位置插入[88,88]\n",
    "print(fan)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[88, 88]\n",
      "[95, 25, 77, 1, 2, 3, 45, 90, 36, 100]\n"
     ]
    }
   ],
   "source": [
    "#可以通过切片替换数据\n",
    "#从某种程度上说，上述的插入其实也是种替换\n",
    "print(fan[3:5])\n",
    "fan[3:5] = [1,2,3]\n",
    "print(fan)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表的方法\n",
    "\n",
    "| 方法 | 含义 |\n",
    "| ---  | ---  |\n",
    "| cmp  | 比较两个列表元素  |\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "长度： 2\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'score' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-3-f4526d9f239d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      2\u001b[0m \u001b[0mls\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;34m'特靠谱'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'特没谱'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'长度：'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mls\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscore\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mmin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscore\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'score' is not defined"
     ]
    }
   ],
   "source": [
    "#列表的操作函数\n",
    "ls = ['特靠谱','特没谱']\n",
    "print('长度：',len(ls))\n",
    "print(score,min(score))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['haha', 'hehe', '特有普', 'heihei', '特靠谱', '特没谱']\n",
      "['haha', 'hehe', '特有普', 'heihei', '特靠谱', '特没谱', 18, '弱冠', '而立']\n"
     ]
    }
   ],
   "source": [
    "#列表的方法\n",
    "#扩充列表.extend(iterable)\n",
    "student.extend(['特靠谱','特没谱'])\n",
    "print(student)\n",
    "newstudent = student+age\n",
    "print(newstudent)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['haha', 'hehe', '特有普', 'heihei']\n"
     ]
    }
   ],
   "source": [
    "#列表的插入 .insert(index,object)\n",
    "student.insert(2,'特有普')\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['haha', 'hehe', '特有普', 'heihei', '特靠谱']\n"
     ]
    }
   ],
   "source": [
    "#移除某个元素 .remove(value)\n",
    "student.remove('特没谱')\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]\n"
     ]
    }
   ],
   "source": [
    "#清除列表内容\n",
    "student.clear()\n",
    "print(student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "#计算值出现了多少次\n",
    "print(student.count('特有普'))\n",
    "#返回数据的第一个位置，找不到就抛ValueError\n",
    "print(student.index('特有普'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "特有普\n"
     ]
    }
   ],
   "source": [
    "#获取指定位置的元素， .pop([index]) index如果不写，默认是最后一个，如果找不到则抛出IndexError\n",
    "print(student.pop(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<list_reverseiterator object at 0x000001ECAE5D7940>\n",
      "[100, 36, 90, 45, 77, 25, 95]\n",
      "95 25 77 45 90 36 100 [100, 36, 90, 45, 77, 25, 95]\n",
      "[95, 25, 77, 45, 90, 36, 100]\n"
     ]
    }
   ],
   "source": [
    "#reversed并不改变score，产生一个反转的迭代器\n",
    "print(reversed(score))\n",
    "print(score)\n",
    "for s in reversed(score):\n",
    "    print(s,end=' ')\n",
    "print(score)\n",
    "#列表反转 .reverse()\n",
    "score.reverse()\n",
    "print(score)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[25, 36, 45, 77, 90, 95, 100]\n",
      "[100, 36, 90, 45, 77, 25, 95]\n",
      "None\n",
      "[25, 36, 45, 77, 90, 95, 100]\n"
     ]
    }
   ],
   "source": [
    "#sorted(iterable, key=None, reverse=False) 函数也可以排序\n",
    "#sorted并不改变score，产生一个新的排好序的列表\n",
    "#sorted的输入不一定是列表，而是一个iterable对象，所以参数可以是字典，元组，集合等\n",
    "print(sorted(score))\n",
    "print(score)\n",
    "#列表排序 .sort(key=None,reverse=False),key表示对什么排序一般是个函数，reverse表示是否倒序\n",
    "print(score.sort())\n",
    "print(score)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[25, 36, 45, 77, 90, 95, 100]\n",
      "[100, 95, 90, 77, 45, 36, 25]\n"
     ]
    }
   ],
   "source": [
    "#倒序\n",
    "print(score)\n",
    "score.sort(reverse=True)\n",
    "print(score)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[25, 36, 45, 77, 90, 95, 100]\n"
     ]
    }
   ],
   "source": [
    "#列表排序 sorted\n",
    "print(sorted(score))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 36, 90, 25, 95, 45, 77]\n",
      "[25, 100, 36, 95, 45, 90, 77]\n"
     ]
    }
   ],
   "source": [
    "#根据key查询，偶数在前，奇数在后\n",
    "#key可以指定一个函数，根据函数的结果排序\n",
    "score = [25, 100, 36, 95, 45, 90, 77]\n",
    "def evenfirst(item):\n",
    "    return item%2\n",
    "print(sorted(score,key=evenfirst))\n",
    "print(score)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[36, 90, 100, 25, 45, 77, 95]\n",
      "[25, 100, 36, 95, 45, 90, 77]\n"
     ]
    }
   ],
   "source": [
    "#在上面的例子中按照奇偶性进行排序，但是在奇数或者偶数内部并没有排序\n",
    "#所以我们可以改进策略，进行多关键字排序，比如先按照奇偶性排，再按照大小排\n",
    "score = [25, 100, 36, 95, 45, 90, 77]\n",
    "def evenfirst(item):\n",
    "    return item%2,item\n",
    "print(sorted(score,key=evenfirst))\n",
    "print(score)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[36, 90, 100, 25, 45, 77, 95]\n",
      "[25, 100, 36, 95, 45, 90, 77]\n"
     ]
    }
   ],
   "source": [
    "#如果使用lambda表达式（参照函数式编程一章），则程序会更加简洁,先按照  x%2排，再按照x排\n",
    "score = [25, 100, 36, 95, 45, 90, 77]\n",
    "print(sorted(score,key=lambda x:(x%2,x)))\n",
    "print(score)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 3, 3, 1, 1, 2, 2, 7, 9]\n",
      "[1, 2, 2, 3, 3, 3, 1, 9, 7]\n"
     ]
    }
   ],
   "source": [
    "#任务：对字符串中字符进行排序，出现次数多的排在前面，相同多的按照值排序\n",
    "nums = [1,2,2,3,3,3,1,9,7]\n",
    "print(sorted(nums, key=lambda x:(-nums.count(x),x)))\n",
    "print(nums)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 94, 60, 97, 87, 67, 50]\n"
     ]
    }
   ],
   "source": [
    "#列表还有些特别用法，可以一句话实现想要的结果，具体原理，学习函数式编程会学习\n",
    "#把学生成绩开根号*10，作为最终成绩\n",
    "from math import sqrt\n",
    "newscore = [ int(sqrt(x)*10) for x in score]\n",
    "print(newscore)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[['门捷列夫', '91', '94', '86', 271], ['伽利略', '91', '91', '61', 243], ['达芬奇', '78', '74', '85', 237], ['刘辉', '61', '97', '73', 231], ['高斯', '88', '67', '75', 230], ['欧拉', '68', '91', '69', 228], ['祖冲之', '91', '72', '60', 223], ['阿基米德', '73', '74', '72', 219], ['哥白尼', '68', '69', '80', 217], ['欧几里得', '74', '77', '65', 216]]\n"
     ]
    }
   ],
   "source": [
    "#任务3.1 成绩排名\n",
    "#在文件stuscore.txt中输入10行数据，每行是姓名，数学，英语，语文。读取数据，用列表存储，最后输出每个人的成绩和总分，并按照总分排名。\n",
    "stuscores=[]\n",
    "#读取数据放stuscores\n",
    "with open('stuscore.txt','r',encoding='utf8') as fstuscore:\n",
    "    line = fstuscore.readline()\n",
    "    while line:\n",
    "        stuscores.append(line.strip().split(','))\n",
    "        line = fstuscore.readline()\n",
    "#求每个人的总分\n",
    "for stuscore in stuscores:\n",
    "    totalscore = int(stuscore[1])+int(stuscore[2])+int(stuscore[3])\n",
    "    stuscore.append(totalscore)\n",
    "\n",
    "#排序\n",
    "def gettotal(score):\n",
    "    return score[4]\n",
    "\n",
    "stuscores.sort(key=gettotal,reverse=True)\n",
    "\n",
    "print(stuscores)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 字典\n",
    "字典里面存放的数据主要是key-value形式，可以通过key找到value。查询速度非常快，数据排序也很容易。字典key可以是能计算hash值得任类意型，值value也是任意类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{}\n",
      "<class 'dict'>\n",
      "True\n",
      "True\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "#字典的创建与初始化\n",
    "empty={}\n",
    "print(empty)\n",
    "print(type(empty))\n",
    "print(empty == dict())\n",
    "\n",
    "scores = dict(yingyu=110,jisuanji=90,shuxue=140)\n",
    "scores2 = {\"yingyu\":110,'jisuanji':90,\"shuxue\":140}\n",
    "scores3 = dict([('yingyu',110),('jisuanji',90),('shuxue',140)])\n",
    "print(scores==scores2)\n",
    "print(scores==scores3)\n",
    "print(scores is scores2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "140\n",
      "None\n",
      "666\n"
     ]
    },
    {
     "ename": "KeyError",
     "evalue": "'yuwen'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-90-86441457afed>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      6\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscores\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'yuwen'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m666\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      7\u001b[0m \u001b[1;31m#通过下标访问不存在的key会出错\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscores\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'yuwen'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m: 'yuwen'"
     ]
    }
   ],
   "source": [
    "#根据key获取value\n",
    "print(scores['shuxue'])\n",
    "#通过get访问不存在的key，回返回None\n",
    "print(scores.get('yuwen'))  \n",
    "#也可以在get获取不到的时候，提供默认值\n",
    "print(scores.get('yuwen',666))\n",
    "#通过下标访问不存在的key会出错\n",
    "print(scores['yuwen'])  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'yingyu': 110, 'jisuanji': 90, 'shuxue': 150, 'yuwen': 110}\n"
     ]
    }
   ],
   "source": [
    "#设置key value\n",
    "scores['shuxue'] = 150\n",
    "scores['yuwen']=110\n",
    "print(scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "#删除key-value对\n",
    "del scores['yuwen']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "150\n",
      "{'yingyu': 110, 'jisuanji': 90, 'yuwen': 110}\n"
     ]
    }
   ],
   "source": [
    "#取出key-value对，并返回value值\n",
    "print(scores.pop('shuxue'))\n",
    "print(scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "666\n"
     ]
    }
   ],
   "source": [
    "#取出key-value对，并返回value值，如果不存在key，则返回默认值\n",
    "print(scores.pop('khbd',666))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('jisuanji', 90)\n"
     ]
    }
   ],
   "source": [
    "#取出一个键值对（具体哪个与实际存储情况相关）\n",
    "print(scores.popitem())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['yingyu', 'jisuanji', 'shuxue'])\n",
      "yingyu\n",
      "jisuanji\n",
      "shuxue\n",
      "yingyu\n",
      "jisuanji\n",
      "shuxue\n",
      "dict_values([110, 90, 140])\n",
      "110\n",
      "90\n",
      "140\n",
      "dict_items([('yingyu', 110), ('jisuanji', 90), ('shuxue', 140)])\n",
      "yingyu:110\n",
      "jisuanji:90\n",
      "shuxue:140\n"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "too many values to unpack (expected 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-4-8ba5d0e840fd>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     13\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mvalue\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mscores\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     14\u001b[0m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'{}:{}'\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 15\u001b[1;33m \u001b[1;32mfor\u001b[0m \u001b[0mk\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mv\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mscores\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     16\u001b[0m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mk\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mv\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mValueError\u001b[0m: too many values to unpack (expected 2)"
     ]
    }
   ],
   "source": [
    "#获取所有key\n",
    "print(scores.keys())\n",
    "for key in scores.keys():\n",
    "    print(key)\n",
    "#可以直接遍历keys\n",
    "for k in scores:\n",
    "    print(k)\n",
    "#获取所有value\n",
    "print(scores.values())\n",
    "for value in scores.values():\n",
    "    print(value)\n",
    "#获取所有的key-value\n",
    "print(scores.items())\n",
    "for key,value in scores.items():\n",
    "    print('{}:{}'.format(key,value))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "{'shuxue': 140, 'yingyu': 110, 'jisuanji': 90}\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "#查看字典长度\n",
    "print(len(scores))\n",
    "#复制字典\n",
    "newscores=scores.copy()\n",
    "print(newscores)\n",
    "print(newscores == scores)\n",
    "print(newscores is scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'yingyu': '及格', 'jisuanji': '及格', 'shuxue': '及格'}\n"
     ]
    }
   ],
   "source": [
    "#字典结合循环的特别用法\n",
    "def ispass(score):\n",
    "    if score>=60:\n",
    "        return '及格'\n",
    "    else:\n",
    "        return '不及格'\n",
    "    \n",
    "scorepass = { k:ispass(v) for k,v in scores.items() }\n",
    "print(scorepass)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入姓名:阿基米德\n",
      "{'姓名': '阿基米德', '数学': 73, '英语': 74, '语文': 72, '总分': 219}\n"
     ]
    }
   ],
   "source": [
    "#任务3.2 成绩查询\n",
    "#在文件stuscore.txt中输入10行数据，每行是姓名，数学，英语，语文。读取数据，用字典存储，用户输入姓名可以查找成绩\n",
    "#\n",
    "stuscores={}\n",
    "#读取数据放stuscores\n",
    "with open('stuscore.txt','r',encoding='utf8') as fstuscore:\n",
    "    line = fstuscore.readline()\n",
    "    while line:\n",
    "        linescore = line.strip().split(',')\n",
    "        stuscores[linescore[0]] = {\"姓名\":linescore[0], \"数学\":int(linescore[1]), \"英语\":int(linescore[2]),\n",
    "                                  \"语文\":int(linescore[3]),\n",
    "                                  \"总分\":int(linescore[1]) + int(linescore[2]) + int(linescore[3])}\n",
    "        line = fstuscore.readline()\n",
    "\n",
    "name = input(\"请输入姓名:\")\n",
    "       \n",
    "print(stuscores[name])\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入一些字符串haha hehe heiheih hoho\n",
      "{'haha': 1, 'hehe': 1, 'heiheih': 1, 'hoho': 1}\n"
     ]
    }
   ],
   "source": [
    "#任务：\n",
    "#1. 从键盘输入一些用空格隔开的字符串\n",
    "#2. 把每个字符串和出现的次数作为字典的key，value存入字典\n",
    "words = input('请输入一些字符串')\n",
    "words = words.split(' ')\n",
    "worddic = {}\n",
    "for word in words:\n",
    "    worddic[word]=worddic.get(word,0) + 1\n",
    "print(worddic)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 元组\n",
    "元组是个很有意思的数据结构，由多个数据构成的一个整体，多个数据之间用逗号隔开，最终所有数据用括号括起来，构成一个新的元组,是不可改动的。所以元组的主要用途就是把多个数据合成一个数据。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, '哈哈', {'yuwen': 100, 'shuxue': 100})\n",
      "<class 'tuple'>\n",
      "3\n",
      "1\n",
      "<class 'tuple'>\n",
      "(1, '哈哈', {'yuwen': 200, 'shuxue': 100})\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-33-aaea76fe7a5d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     16\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstudent\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     17\u001b[0m \u001b[1;31m#就是不能修改这个字符串，如果修改了，相当于变成一个新的对象了，和上面语句还是有区别的\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 18\u001b[1;33m \u001b[0mstudent\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'呵呵'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "#创建一个空元组\n",
    "empty = ()\n",
    "#创建一个元组，包含学生的序号，姓名，等信息\n",
    "student = (1,'哈哈',{'yuwen':100,'shuxue':100})\n",
    "print(student)\n",
    "print(type(student))\n",
    "print(len(student))\n",
    "#访问元组中某个元素\n",
    "print(student[0])\n",
    "#元组可以只有一个值\n",
    "student2 = (2,)\n",
    "print(type(student2))\n",
    "#元组里面的值是不能改变的，赋值会报TypeError\n",
    "#但是如果里面是个可变对象也是可以通过下列方式改变的\n",
    "student[2]['yuwen'] = 200\n",
    "print(student)\n",
    "#就是不能修改这个字符串，如果修改了，相当于变成一个新的对象了，和上面语句还是有区别的\n",
    "student[1]='呵呵'\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "(1, '哈哈')\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "#元组长度\n",
    "print(len(student))\n",
    "#元组切片\n",
    "print(student[:2])\n",
    "#判断元组中是否包含某个数据\n",
    "print('哈哈' in student)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(666, '任俊新', '计算机')\n",
      "<class 'tuple'>\n",
      "666 任俊新 计算机\n"
     ]
    }
   ],
   "source": [
    "#可以把多个数据合起来作为参数，也可以把参数拆开来\n",
    "teacher = 666,'任俊新','计算机'\n",
    "print(teacher)\n",
    "print(type(teacher))\n",
    "\n",
    "id,name,course = teacher\n",
    "print(id,name,course)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x=6\ty=5\n"
     ]
    }
   ],
   "source": [
    "#通过元组进行数据交换\n",
    "x=5\n",
    "y=6\n",
    "x,y = y,x\n",
    "print(\"x={}\\ty={}\".format(x,y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 "
     ]
    }
   ],
   "source": [
    "#Fibonacci number\n",
    "def fibonacci(n):\n",
    "    a,b=0,1\n",
    "    for i in range(n):\n",
    "        print(a,end=' ')\n",
    "        a,b = b, a+b\n",
    "    \n",
    "fibonacci(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 10\n",
      "1 20\n",
      "2 30\n",
      "yuwen 200\n",
      "shuxue 100\n"
     ]
    }
   ],
   "source": [
    "#可以元组获取enumberate函数获取的索引和值\n",
    "for i,v in enumerate([10,20,30]):\n",
    "    print(i,v)\n",
    "#可以通过元组获取字典的key-value\n",
    "for key,value in student[2].items():\n",
    "    print(key,value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "热巴 vs 薛之谦\n",
      "佟丽娅 vs 毛不易\n",
      "娜扎 vs amy\n",
      "杨幂 vs 香菜\n",
      "赵今麦 vs 陈小春\n",
      "baby vs 李克勤\n",
      "赵丽颖 vs 梦龙\n"
     ]
    }
   ],
   "source": [
    "#zip函数，可以关联两个列表，便利zip的结果，得到一个个元组\n",
    "#下面以两队明星参加我是歌神歌唱比赛的名单，我们可以很轻松的产生对战表\n",
    "teama = ['热巴','佟丽娅','娜扎','杨幂','赵今麦','baby','赵丽颖']\n",
    "teamb = ['薛之谦','毛不易','amy','香菜','陈小春','李克勤','梦龙','霉霉']\n",
    "for a,b in zip(teama,teamb):\n",
    "    print('{} vs {}'.format(a,b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入A组队员:haha hehe\n",
      "请输入B组队员:ha he\n",
      "['haha', 'hehe'] ['ha', 'he']\n",
      "[('haha', 'ha'), ('haha', 'he'), ('hehe', 'ha'), ('hehe', 'he')]\n"
     ]
    }
   ],
   "source": [
    "#任务3.3 任意输入两组不超过5人的团队，输出所有可能的pk组合（笛卡尔积）\n",
    "teama = input(\"请输入A组队员:\").strip().split(' ')\n",
    "teamb = input(\"请输入B组队员:\").strip().split(' ')\n",
    "print(teama,teamb)\n",
    "teamab = [(x,y) for x in teama for y in teamb]\n",
    "print(teamab)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 集合\n",
    "集合是多个不重复数据的组合，是无序的。定义集合使用{}，数据之间用逗号隔开。通过hash的方式存储元素，所以集合中查找数据要比列表快很多。同时支持集合的并交差等操作。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n",
      "<class 'set'>\n",
      "0\n",
      "<class 'set'>\n",
      "7\n",
      "{'羽毛球', '篮球', '滑板', '乒乓球', '跷跷板', '喜欢个球', '足球'}\n",
      "<class 'set'>\n",
      "7\n",
      "{'羽毛球', '篮球', '滑板', '乒乓球', '跷跷板', '喜欢个球', '足球'}\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "#空集合,不能用{}表示空集合，因为和空字典冲突了\n",
    "emptyset={}\n",
    "emptyset2=set()\n",
    "print(type(emptyset))\n",
    "print(type(emptyset2))\n",
    "print(len(emptyset2))\n",
    "#集合的初始化\n",
    "#我喜欢的运动\n",
    "sports = {'篮球','足球','乒乓球','羽毛球','喜欢个球','滑板','跷跷板'}\n",
    "#集合中，不能有重复的值，所以虽然这个列表中有，最终集合也不会有两个同样的球的\n",
    "sports2 = set(['篮球','足球','乒乓球','羽毛球','喜欢个球','滑板','跷跷板','篮球',\"足球\"])\n",
    "sports3 = {'LOL','绝地求生','王者荣耀','抖音','篮球','足球','羽毛球','跑路','划水'}\n",
    "print(type(sports))\n",
    "print(len(sports))\n",
    "print(sports)\n",
    "print(type(sports2))\n",
    "print(len(sports2))\n",
    "print(sports2)\n",
    "print(sports==sports2)\n",
    "print(sports is sports2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'羽毛球', '滑板', '足球', '太极拳', '乒乓球', '篮球', '跷跷板', '喜欢个球'}\n",
      "羽毛球\n",
      "滑板\n",
      "set()\n",
      "{'羽毛球', '滑板', '足球', '太极拳', '篮球', '跷跷板'}\n"
     ]
    }
   ],
   "source": [
    "#集合中元素的增加\n",
    "sports.add('太极拳')\n",
    "print(sports)\n",
    "#集合中移出数据,具体哪个不清楚\n",
    "print(sports2.pop())\n",
    "print(sports2.pop())\n",
    "#集合数据的清除\n",
    "sports2.clear()\n",
    "print(sports2)\n",
    "#删除元素，如果不存在也不报错\n",
    "sports.discard('乒乓球')\n",
    "#删除元素，如果不存在则报错KeyError\n",
    "sports.remove('喜欢个球')\n",
    "print(sports)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'羽毛球', '篮球', '滑板', '划水', '抖音', 'LOL', '跷跷板', '跑路', '绝地求生', '王者荣耀', '乒乓球', '喜欢个球', '足球'}\n",
      "{'羽毛球', '篮球', '足球'}\n",
      "{'滑板', '乒乓球', '跷跷板', '喜欢个球'}\n",
      "{'王者荣耀', '划水', '抖音', 'LOL', '跑路', '绝地求生'}\n",
      "{'滑板', '王者荣耀', '划水', '乒乓球', '抖音', 'LOL', '跷跷板', '喜欢个球', '跑路', '绝地求生'}\n"
     ]
    }
   ],
   "source": [
    "#集合的并\n",
    "print(sports | sports3)\n",
    "#集合的交\n",
    "print(sports & sports3)\n",
    "#集合的差\n",
    "print(sports-sports3)\n",
    "print(sports3-sports)\n",
    "#集合的对称差\n",
    "print(sports^sports3)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "#判断集合的包含关系\n",
    "print((sports & sports3)<sports)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入你的爱好:a b\n",
      "请输入你男(女)神的爱好:b c\n",
      "{'b', 'a'} {'c', 'b'}\n",
      "两个人的爱好 {'c', 'b', 'a'}\n",
      "两个人共同爱好 {'b'}\n",
      "自己喜欢，男(女)神不喜欢 {'a'}\n"
     ]
    }
   ],
   "source": [
    "#任务3.4 任意输入两组有交集的集合，然后计算两个集合的 并交差\n",
    "hobbya = set(input(\"请输入你的爱好:\").strip().split(' '))\n",
    "hobbyb = set(input(\"请输入你男(女)神的爱好:\").strip().split(' '))\n",
    "print(hobbya, hobbyb)\n",
    "# 并交叉\n",
    "print(\"两个人的爱好\",hobbya|hobbyb)\n",
    "print(\"两个人共同爱好\",hobbya&hobbyb)\n",
    "print(\"自己喜欢，男(女)神不喜欢\",hobbya - hobbyb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入多个字符串用空格隔开：haha 哈哈\n",
      "没有重复\n"
     ]
    }
   ],
   "source": [
    "# 任务3.5\n",
    "# 输入一段空格隔开的字符串，判断每个隔开的字符串有没有重复\n",
    "string = input('请输入多个字符串用空格隔开：')\n",
    "strings = string.split(' ')\n",
    "if len(strings) == len(set(strings)):\n",
    "    print('没有重复')\n",
    "else:\n",
    "    print(\"有重复\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
